package jlib.component.core
{
	import flash.display.Shape;
	import flash.events.Event;
	import flash.geom.Rectangle;
	
	import jlib.utils.GraphicsUtil;
	/**
	 * Border 클래스.
	 * 컴포넌트의 외곽선 객체.
	 * @author Park Jong Hee 
	 */	
	public class Border extends Shape {
		private var m_width:Number, m_height:Number;
		private var m_dashSize:Number;
		private var m_gapSize:Number;
		
		private var m_thickness:int;
		private var m_color:uint;
		private var m_type:String;
		private var m_round:int;
		private var m_position:String;
		
		private var m_caps:String;
		private var m_joint:String;
		private var m_scaleMode:String;
		private var m_visibleLeft:Boolean;
		private var m_visibleTop:Boolean;
		private var m_visibleRight:Boolean;
		private var m_visibleBottom:Boolean;
		
		/**
		 * Border 클래스 생성자.
		 * @param $thickness 선의 뚜께
		 * @param $color 선의 색상
		 * @param $round 선의 Round
		 * @param $type 선의 타입.
		 * @param $position 선의 위치.
		 */		
		public function Border($thickness:int=0, $color:uint=0x000000, $round:int=0, $type:String='solid', $position:String='middle') {
			m_width = m_height = 1;
			setThickness($thickness), setColor($color), setRound($round), setType($type), setPosition($position);
			setScaleMode("none");
			setGapSize(3); setDashSize(3);
			m_visibleBottom = m_visibleLeft = m_visibleRight = m_visibleTop = true;
		}
		
		public function getThickness(): int { return m_thickness; }
		public function setThickness($thickness:int): void {
			if(m_thickness == $thickness) return ;
			m_thickness = $thickness;
			update();
		}
		
		public function getRound(): int { return m_round; }
		public function setRound($round:int): void {
			if(m_round == $round) return ;
			m_round = $round;
			update();
		}
		public function getColor(): uint { return m_color; }
		public function setColor($color:uint): void {
			if(m_color == $color) return ;
			m_color = $color;
			update();
		}
		/**
		 * 선의 외곽선의 위치를 결정합니다. 
		 * @return 외곽선의 종류.
		 */		
		public function getPosition():String { return m_position; }
		public function setPosition($position:String): void
		{
			if(!$position) throw new Error('position에 null 값이 들어오면 안됩니다.');
			if(m_position == $position) return ;
			m_position = $position;
			update();
		}
		
		public function getType(): String { return m_type; }
		public function setType($type:String): void {
			if(!$type) throw new Error('type에 null 값이 들어오면 안됩니다.');
			if(m_type == $type) return ;
			m_type = $type;
			update();
		}
		
		public function update(e:Event=null): void  { 
			draw(e); 
		}
		
		private function draw(e:Event=null): void
		{
			graphics.clear();
			if(Boolean(m_thickness)) graphics.lineStyle(m_thickness, m_color, 1, false, m_scaleMode, m_caps, m_joint);
			var rect:Rectangle = assistDrawRect();
			var radius:int = m_round/2;
			if(m_type == BorderType.SOILD) {
				if(m_visibleLeft) {
					GraphicsUtil.drawArc(graphics,rect.x+radius,rect.y+radius,135,45,radius);
					GraphicsUtil.drawLine(graphics,rect.x,rect.y+radius, rect.x,(rect.y+rect.height)-radius);
					GraphicsUtil.drawArc(graphics, rect.x+radius,(rect.y+rect.height)-radius,180,45,radius);
				}
				if(m_visibleBottom) {
					GraphicsUtil.drawArc(graphics, rect.x+radius,(rect.y+rect.height)-radius,225,45,radius);
					GraphicsUtil.drawLine(graphics, rect.x+radius,(rect.y+rect.height) , (rect.x+rect.width)-radius,(rect.y+rect.height));
					GraphicsUtil.drawArc(graphics,(rect.x+rect.width)-radius,(rect.y+rect.height)-radius,270,45,radius);
				}
				if(m_visibleRight){
					GraphicsUtil.drawArc(graphics,(rect.x+rect.width)-radius,(rect.y+rect.height)-radius,310,45,radius);
					GraphicsUtil.drawLine(graphics,(rect.x+rect.width),(rect.y+rect.height)-radius, (rect.x+rect.width),rect.y+radius);
					GraphicsUtil.drawArc(graphics,(rect.x+rect.width)-radius,rect.y+radius,0,45,radius);
				}
				if(m_visibleTop){
					GraphicsUtil.drawArc(graphics,(rect.x+rect.width)-radius,rect.y+radius,45,45,radius);
					GraphicsUtil.drawLine(graphics,(rect.x+rect.width)-radius,rect.y, rect.x+radius,rect.y);
					GraphicsUtil.drawArc(graphics,rect.x+radius,rect.y+radius,90,45,radius);
				}
			}else {
				if(m_visibleLeft) {
					GraphicsUtil.drawDashArc(graphics,rect.x+radius,rect.y+radius,135,45,radius, m_dashSize, m_gapSize);
					GraphicsUtil.drawDashLine(graphics,rect.x,rect.y+radius, rect.x,(rect.y+rect.height)-radius, m_dashSize, m_gapSize);
					GraphicsUtil.drawDashArc(graphics, rect.x+radius,(rect.y+rect.height)-radius,180,45,radius, m_dashSize, m_gapSize);
				}
				if(m_visibleBottom) {
					GraphicsUtil.drawDashArc(graphics, rect.x+radius,(rect.y+rect.height)-radius,225,45,radius, m_dashSize, m_gapSize);
					GraphicsUtil.drawDashLine(graphics, rect.x+radius,(rect.y+rect.height) , (rect.x+rect.width)-radius,(rect.y+rect.height), m_dashSize, m_gapSize);
					GraphicsUtil.drawDashArc(graphics,(rect.x+rect.width)-radius,(rect.y+rect.height)-radius,270,45,radius, m_dashSize, m_gapSize);
				}
				if(m_visibleRight){
					GraphicsUtil.drawDashArc(graphics,(rect.x+rect.width)-radius,(rect.y+rect.height)-radius,310,45,radius, m_dashSize, m_gapSize);
					GraphicsUtil.drawDashLine(graphics,(rect.x+rect.width),(rect.y+rect.height)-radius, (rect.x+rect.width),rect.y+radius, m_dashSize, m_gapSize);
					GraphicsUtil.drawDashArc(graphics,(rect.x+rect.width)-radius,rect.y+radius,0,45,radius, m_dashSize, m_gapSize);
				}
				if(m_visibleTop){
					GraphicsUtil.drawDashArc(graphics,(rect.x+rect.width)-radius,rect.y+radius,45,45,radius, m_dashSize, m_gapSize);
					GraphicsUtil.drawDashLine(graphics,(rect.x+rect.width)-radius,rect.y, rect.x+radius,rect.y, m_dashSize, m_gapSize);
					GraphicsUtil.drawDashArc(graphics,rect.x+radius,rect.y+radius,90,45,radius, m_dashSize, m_gapSize);
				}
			}
		}
		
		private function assistDrawRect(): Rectangle
		{
			var result:Rectangle;
			if(m_position == BorderPosition.INNER) result = new Rectangle(m_thickness*0.5,m_thickness*0.5, m_width-m_thickness, m_height-m_thickness); 
			else if(m_position == BorderPosition.MIDDLE) result = new Rectangle(0,0, m_width, m_height);
			else if(m_position == BorderPosition.OUTER) result = new Rectangle(-m_thickness*0.5,-m_thickness*0.5, m_width+m_thickness, m_height+m_thickness);
			return result;
		}
		
		public function getScaleMode(): String { return m_scaleMode; }
		public function setScaleMode($mode:String): void {
			if(m_scaleMode == $mode) return ;
			m_scaleMode = $mode;
			update();
		}
				
		override public function get width(): Number { return m_width; }
		override public function set width(value:Number): void 
		{
			if (value != m_width) {
				m_width = value; 
				update();
			}
		}
		
		override public function get height(): Number { return m_height; }
		override public function set height(value:Number): void 
		{ 
			if (value != m_height) {
				m_height = value;
				update();
			}
		}
		
		public function getGapSize():Number { return m_gapSize; }
		public function setGapSize(value:Number):void {
			if(m_gapSize == value) return ;
			m_gapSize = value;
			update();
		}
		
		public function getDashSize():Number { return m_dashSize; }
		public function setDashSize(value:Number):void {
			if(m_dashSize == value) return ;
			m_dashSize = value;
			update();
		}
		
		public function getCapsStyle(): String { return m_caps; }
		public function setCapsStyle($capsStyle:String): void {
			if(m_caps == $capsStyle) return ;
			m_caps = $capsStyle;
			update();
		}
		
		public function getJointSytle(): String { return m_joint; }
		public function setJointStyle($jointStyle:String) : void {
			if(m_joint == $jointStyle) return ;
			m_joint = $jointStyle;
			update();
		}
		
		public function getVisibleLeft():Boolean { return m_visibleLeft; }
		public function setVisibleLeft($bool:Boolean): void {
			if(m_visibleLeft == $bool) return ;
			m_visibleLeft = $bool;
			update();
		}
		
		public function getVisibleTop():Boolean { return m_visibleTop; }
		public function setVisibleTop($bool:Boolean): void {
			if(m_visibleTop == $bool) return ;
			m_visibleTop = $bool;
			update();
		}
		
		public function getVisibleRight():Boolean { return m_visibleRight; }
		public function setVisibleRight($bool:Boolean): void {
			if(m_visibleRight == $bool) return ; 
			m_visibleRight = $bool;
			update();
		}
		
		public function getVisibleBottom():Boolean { return m_visibleBottom; }
		public function setVisibleBottom($bool:Boolean): void {
			if(m_visibleBottom == $bool) return ;
			m_visibleBottom = $bool;
			update();
		}

	}//c
}